﻿using AutoMapper;
using JiebaNet.Segmenter.Common;
using ManagementApi.Authorizers;
using ManagementApi.Models;
using ManagementApi.Models.Common;
using ManagementApi.Models.Manage.ProjectGroupMember;
using ManagementApi.Models.Person;
using ManagementApi.Mvc;
using ManagementApi.Mvc.ApplicationContexts;
using ManagementApi.Services;
using ManagementApi.Services.Import;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Minio.DataModel;
using Modules;
using Modules.Corp;
using Modules.Person;
using Modules.Project;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using PmSoft.Exceptions;
using PmSoft.Utilities;
using static Modules.Person.PersonConstants;

namespace ManagementApi.Controllers.ManagerPannel
{
    /// <summary>
    /// 银行信息相关接口
    /// </summary>
    [Route("/api/v1/manager/personbank")]
    [ApiController]
    [Authorize(Roles = "Manager")]
    public class PersonBankController : ControllerBase
    {
        private readonly PersonBankService personBankService;
        private readonly ProjectManagerApplicationContext applicationContext;
        private readonly CorpService corpService;
        private readonly ProjectService projectService;
        private readonly ProjectGroupService projectGroupService;
        private readonly PersonService personService;
        private readonly PersonCorpContractService personCorpContractService;
        private readonly ProjectGroupMemberService projectGroupMemberService;
        private readonly ExportService exportService;
        private readonly ImportService importService;
        private readonly IMapper mapper;
        private readonly PersonBankOwnAuthorizer ownAuthorizer;

        public PersonBankController(PersonBankService personBankService, ProjectManagerApplicationContext applicationContext, IMapper mapper, PersonCorpContractService personCorpContractService, PersonService personService, ProjectGroupService projectGroupService, ProjectService projectService, CorpService corpService, ProjectGroupMemberService projectGroupMemberService, ExportService exportService, ImportService importService, PersonBankOwnAuthorizer ownAuthorizer)
        {
            this.personBankService = personBankService;
            this.applicationContext = applicationContext;
            this.mapper = mapper;
            this.personCorpContractService = personCorpContractService;
            this.projectGroupService = projectGroupService;
            this.projectService = projectService;
            this.corpService = corpService;
            this.personService = personService;
            this.projectGroupMemberService = projectGroupMemberService;
            this.importService = importService;
            this.ownAuthorizer = ownAuthorizer;
            this.exportService = exportService;
        }

        /// <summary>
        /// 新增银行信息
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPost("create")]
        public ApiResult CreatePersonBank(PersonBankEditForm form)
        {
            PersonBank entity = new();
            mapper.Map(form, entity);
            entity.IdCard = form.IdCard;
            entity.CreateTime = DateTime.Now;
            personBankService.CreateOrUpdate(entity);
            return ApiResult.Success("创建成功");
        }

        /// <summary>
        /// 编辑银行信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public ApiResult UpdatePersonBank(int id, PersonBankEditForm form)
        {
            PersonBank data = personBankService.GetPersonBank(id) ?? throw new BusinessException("银行卡信息不存在");

            #region 数据权限验证

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(id);

            #endregion 数据权限验证

            if (data == null) return ApiResult.Failure("银行信息不存在");
            mapper.Map(form, data);

            personBankService.CreateOrUpdate(data);
            return ApiResult.Success("修改成功");
        }

        /// <summary>
        /// 银行信息表单数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="corpId"></param>
        /// <returns></returns>
        [HttpGet("{id}/form")]
        public ApiResult<PersonBankEditForm> GetPersonBank(int id, int corpId)
        {
            PersonBank? data = personBankService.GetPersonBank(id);
            if (data == null)
                return ApiResult<PersonBankEditForm>.Failure("银行信息不存在");
            return ApiResult<PersonBankEditForm>.Success(data.AsForm(corpId));
        }

        /// <summary>
        /// 获取银行信息列表(分页)
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <param name="pageNum">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns></returns>
        [HttpGet("page")]
        public ApiResult<PageDto<PersonBankDto>> GetPersonBanks([FromQuery] PersonBankQuery query, int pageNum = 1, int pageSize = 20)
        {
            query.ProjectId = applicationContext.CurrentProjectInfo.ProjectId;
            var data = personBankService.GetPersonBanks(query, pageNum, pageSize);
            var dtos = data.AsPageDto(source => { return source.AsPersonBankDto(); });
            return ApiResult<PageDto<PersonBankDto>>.Success(dtos);
        }

        /// <summary>
        /// 获取银行信息列表(分页)
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        ////[HttpGet("page")]
        //public ApiResult<PageDto<PersonBankDto>> GetUseEmployees([FromQuery] ProjectGroupMemberQuery query, int pageNum = 1, int pageSize = 20)
        //{
        //    query.ProjectId = applicationContext.CurrentProjectInfo.ProjectId;
        //    var data = projectGroupMemberService.GetProjectGroupMembers(query, pageNum, pageSize);
        //    var dtos = data.AsPageDto(source => { return source.AsPersonBankDto(); });
        //    return ApiResult<PageDto<PersonBankDto>>.Success(dtos);
        //}

        /// <summary>
        /// 导入银行卡校验
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost("import")]
        public ApiResult<IEnumerable<PersonBankImportDto>> UploadExcel(IFormFile file)
        {
            IEnumerable<PersonBankImportDto> data = importService.VerifyPersonBankExcelToList(file);
            return ApiResult<IEnumerable<PersonBankImportDto>>.Success(data);
        }

        /// <summary>
        /// 导入提交银行卡
        /// </summary>
        /// <param name="forms"></param>
        /// <returns></returns>
        [HttpPost("saveImport")]
        public ApiResult SaveImport(IEnumerable<PersonBankEditForm> forms)
        {
            List<PersonBank> personBanks = mapper.Map<List<PersonBank>>(forms);

            personBankService.ImportSubmit(personBanks, applicationContext.CurrentProjectInfo.ProjectId);
            return ApiResult.Success("操作成功");
        }

        /// <summary>
        /// 导出选中的人员工资卡模板
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        [HttpPost("exportCheckedBankTemp")]
        public IActionResult ExportCheckedBankTemp(List<ExportCheckedUsesReq> input)
        {
            if (input?.Count == 0)
            {
                throw new BusinessException("请选择要导出的数据");
            }
            IWorkbook workbook = new XSSFWorkbook();

            // 创建一个新的工作表
            ISheet sheet = workbook.CreateSheet("Sheet1");
            // 创建列并设置最小宽度
            int columnWidth = 20;
            int columnIndex = 0;
            sheet.SetColumnWidth(columnIndex, columnWidth * 256); // 设定列宽度，参数为1/256个字符宽度

            // 自动调整列宽
            for (int i = 0; i < 7; i++)
            {
                // 自动调整列宽
                //sheet.AutoSizeColumn(i);
                sheet.SetColumnWidth(i, Math.Max(columnWidth * 256, sheet.GetColumnWidth(i)));
            }
            //表头
            exportService.CellRange(sheet, workbook, 0, 0, "姓名", "身份证号", "工资卡类型", "发卡银行", "银行卡号");
            exportService.SetCellDropdownList(sheet, 2, 2, Enum.GetNames<工资卡类型>());
            var banks = (DictDto.Instance).LoadBankTypeDIC().Select(o => o.Label).ToArray();
            exportService.SetCellDropdownList(sheet, 3, 3, banks);
            int index = 1;
            foreach (var item in input)
            {
                exportService.CellRange(sheet, workbook, index, 0, item.Name, item.IdCard, "", "", "");
                index++;
            }

            // 将工作簿保存到内存流中
            using (MemoryStream memoryStream = new MemoryStream())
            {
                workbook.Write(memoryStream);

                // 设置要下载的文件名
                string fileName = $"{DateTime.Now.ToString("yyyy-MM-dd")}工资卡模板.xlsx";

                // 返回文件内容结果
                return File(memoryStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
            }
        }
    }
}